/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "DeMuxer.h"
#include <hilog/log.h>
#include <multimedia/player_framework/native_averrors.h>
#include <multimedia/player_framework/native_avcodec_base.h>
#include <multimedia/player_framework/native_avformat.h>
#include <multimedia/player_framework/native_avmemory.h>
#include "compressVideo/compressTools/Tools.h"
using namespace std;
#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN 0x3200
#define LOG_TAG "videoCompressor"

DeMuxer::~DeMuxer() 
{ 
    Release(); 
}

int32_t DeMuxer::CreateDemuxer(int32_t fd, int32_t offset, int64_t size) 
{
    source = OH_AVSource_CreateWithFD(fd, offset, size);
    if (!source) {
        OH_LOG_ERROR(LOG_APP, "compressTrace|create deMuxer source failed");
        return AV_ERR_UNKNOWN;
    }

    sourceFormat = OH_AVSource_GetSourceFormat(source);
    if (!sourceFormat) {
        OH_LOG_ERROR(LOG_APP, "compressTrace|create deMuxer getSourceFormat failed");
        return AV_ERR_UNKNOWN;
    }
    OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &trackCount);
    deMuxer = OH_AVDemuxer_CreateWithSource(source);
    GetTrackInfo();
    OH_AVFormat_Destroy(sourceFormat);
    sourceFormat = nullptr;
    return AV_ERR_OK;
}

void DeMuxer::GetTrackInfo() 
{
    int trackType = -1;
    for (int32_t index = 0; index < trackCount; index++) {
        OH_AVDemuxer_SelectTrackByID(deMuxer, index);
        OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(source, index);
        OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &trackType);
        if (trackType == MEDIA_TYPE_VID) {
            OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_WIDTH, &width);
            OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_HEIGHT, &height);
            OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_ROTATION, &rotation);
            OH_AVFormat_GetDoubleValue(trackFormat, OH_MD_KEY_FRAME_RATE, &frameRate);
            OH_AVFormat_GetLongValue(trackFormat, OH_MD_KEY_BITRATE, &bitrate);
            OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_PROFILE, &keyProfile);
            char *videoTemp;
            OH_AVFormat_GetStringValue(trackFormat, OH_MD_KEY_CODEC_MIME, const_cast<char const **>(&videoTemp));
            vTrackId = index;
            videoMime = videoTemp;
            mutexManager->vTrackId = vTrackId;
        }

        if (trackType == MEDIA_TYPE_AUD) {
            aTrackId = index;
            OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_AUD_CHANNEL_COUNT, &audioChannelCount);   // 音频通道数
            OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_AUD_SAMPLE_RATE, &audioSampleRate);       // 音频采样率
            OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, &audioSampleFormat); // 音频位深
            OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_AAC_IS_ADTS, &aacIsADTS);
            OH_AVFormat_SetLongValue(trackFormat, OH_MD_KEY_CHANNEL_LAYOUT, 2); // 音频声道类型 立体
            char *audioTemp;
            OH_AVFormat_GetStringValue(trackFormat, OH_MD_KEY_CODEC_MIME, const_cast<char const **>(&audioTemp));
            OH_AVFormat_GetLongValue(trackFormat, OH_MD_KEY_BITRATE, &audioBitrate);
            audioMime = audioTemp;
            mutexManager->aTrackId = aTrackId;
        }
        OH_AVFormat_Destroy(trackFormat);
        trackType = -1;
    }
}

void DeMuxer::RegisterMuxerManager(MutexManager *m) 
{ 
    mutexManager = m; 
}

void DeMuxer::Release() 
{
    if (source != nullptr) {
        OH_AVSource_Destroy(source);
        source = nullptr;
    }
    if (deMuxer != nullptr) {
        OH_AVDemuxer_Destroy(deMuxer);
        deMuxer = nullptr;
    }
}

int32_t DeMuxer::DestroyDemuxer() 
{
    Release();
    return AV_ERR_OK;
}